package gqz.mvvm.view.custom;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import java.util.Random;

import gqz.mvvm.R;

/**
 * Created by Administrator on 2017/12/8.
 */

public class HeartLayout extends RelativeLayout {

    private final String TAG = "HeartView--";

    private Context context;
    private Random random;

    int width = 300, height = 600;
    int heartW = 48, heartH = 48;
    LayoutParams params;

    int[] heartRes = {R.mipmap.heart_blue, R.mipmap.heart_brown, R.mipmap.heart_green,
            R.mipmap.heart_orange, R.mipmap.heart_pink, R.mipmap.heart_red, R.mipmap.heart_violet,
            R.mipmap.heart_yellow};
    Drawable[] hearts = new Drawable[heartRes.length];


    public HeartLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    private void init() {
        for (int i = 0; i < hearts.length; i++) {
            hearts[i] = ContextCompat.getDrawable(context, heartRes[i]);//getResources().getDrawable 过期的替代方法
        }
        //获取图的宽高 用于后面的计算
        heartW = hearts[0].getIntrinsicWidth();
        heartH = hearts[0].getIntrinsicHeight();
        //定义心型图片出现的位置，底部 水平居中
        params = new LayoutParams(heartW, heartH);
        params.addRule(ALIGN_PARENT_RIGHT, TRUE);
        params.addRule(ALIGN_PARENT_BOTTOM, TRUE);

        random = new Random();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int modeW = MeasureSpec.getMode(widthMeasureSpec);
        int modeH = MeasureSpec.getMode(heightMeasureSpec);
        int sizeW = MeasureSpec.getSize(widthMeasureSpec);
        int sizeH = MeasureSpec.getSize(heightMeasureSpec);

        if (modeW == MeasureSpec.EXACTLY) {
            width = sizeW;
        } else {
            width = Math.min(width, sizeW);
        }
        if (modeH == MeasureSpec.EXACTLY) {
            height = sizeH;
        } else {
            height = Math.min(height, sizeH);
        }

        width = getMeasuredWidth();
        height = getMeasuredHeight();

        setMeasuredDimension(width, height);
    }

    /**
     * 常用的几种插值器：
     * AccelerateInterpolator 开始慢
     * AccelerateDecelerateInterpolator 开始和结束慢
     * AnticipateInterpolator 开始时向后
     * AnticipateOvershootInterpolator 开始时向后退一点，结束时超出一点然后回弹
     * BounceInterpolator 动画结束的时候弹起
     * CycleInterpolator 循环播放特定的次数，速率改变沿着正弦曲线
     * DecelerateInterpolator 结束慢，创建的时候，可以传factor值，如DecelerateInterpolator(2f)，值越大结束时越慢
     * LinearInterpolator 匀速
     * OvershootInterpolator 结束时超出一点然后回弹，创建的时候，可以传tension值，OvershootInterpolator(0.8f)，值越大超出越多
     */

    //爱心出现的动画
    private AnimatorSet getAppearAnimator(View target) {
        ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, 0, 1);
        ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, 0, 1);
        AnimatorSet set = new AnimatorSet();
        set.setDuration(300);
        set.setInterpolator(new LinearInterpolator());//线性插值器
//        set.playSequentially(scaleX,scaleY);//多个动画 顺序执行
        set.playTogether(scaleX, scaleY);//多个动画 同时执行
        set.setTarget(target);
        return set;
    }

    //爱心上升的动画

    /**
     * 贝塞尔曲线的动画实现
     */
    private ValueAnimator getBezierValueAnimator(View target) {
        BezierEvaluator evaluator = new BezierEvaluator(getPointF(2, target.getX()), getPointF(1, target.getX()));
        //第一个PointF传入的是初始点的位置,第二个是结束点（结束点在一定范围内随机）
        PointF pointStart = new PointF(target.getX(), target.getY());
        PointF pointEnd = new PointF(target.getX() + (random.nextInt(200) - 100), height / 2 - random.nextInt(height / 6));
        ValueAnimator anim = ValueAnimator.ofObject(evaluator, pointStart, pointEnd);
        anim.addUpdateListener(new BezierListenr(target));
        anim.setInterpolator(new DecelerateInterpolator());
        anim.setTarget(target);
        anim.setDuration(3000);
        return anim;
    }

    /**
     * 获取中间的两个点
     */
    private PointF getPointF(int scale, float x) {
        PointF pointF = new PointF();
        pointF.x = random.nextInt(100) - 50 + x;//控制 x 轴活动范围,看效果来，随意~~
        //再Y轴上 为了确保第二个点 在第一个点之上,我把Y分成了上下两半 这样动画效果好一些  也可以用其他方法
        pointF.y = height - height / (3 * scale);
        return pointF;
    }

    /**
     * 只有在回调里使用了计算的值,才能真正做到曲线运动
     */
    private class BezierListenr implements ValueAnimator.AnimatorUpdateListener {
        private View target;

        public BezierListenr(View target) {
            this.target = target;
        }

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            //这里获取到贝塞尔曲线计算出来的的x y值 赋值给view 这样就能让爱心随着曲线走啦
            PointF pointF = (PointF) animation.getAnimatedValue();
            target.setX(pointF.x);
            target.setY(pointF.y);
            // alpha动画
            target.setAlpha(1 - animation.getAnimatedFraction());
        }
    }

    /**
     * 动画监听，动画结束后，removeView
     */
    private class AnimEndListener extends AnimatorListenerAdapter {
        private View target;

        public AnimEndListener(View target) {
            this.target = target;
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            //因为不停的add 导致子view数量只增不减,所以在view动画结束后remove掉
            removeView((target));
//            count--;
//            Log.v(TAG, "count:" + count);
        }
    }

    //合并两种动画
    private AnimatorSet getAnimator(View target) {
        AnimatorSet anim1 = getAppearAnimator(target);
        ValueAnimator anim2 = getBezierValueAnimator(target);
        AnimatorSet set = new AnimatorSet();
//        set.setInterpolator();
        set.playSequentially(anim1, anim2);
        set.setTarget(target);
        return set;
    }

//    int count = 0;

    //供外部调用添加爱心
    public void addHeart(float x, float y) {
        ImageView heart = new ImageView(getContext());
        heart.setBackground(hearts[random.nextInt(hearts.length)]);
        heart.setX(x);
        heart.setY(y + 20);
//        heart.setLayoutParams(params);
        addView(heart);
//        count++;
//        Log.v(TAG, "count:" + count);
        Animator set = getAnimator(heart);
        set.addListener(new AnimEndListener(heart));
        set.start();
    }
}
